<?php

/**
 * This is the model class for table "{{system_menu}}".
 *
 * The followings are the available columns in table '{{system_menu}}':
 * @property integer $id
 * @property integer $parent_id
 * @property string $name
 * @property string $link
 * @property integer $level
 * @property integer $display_order
 * @property string $description
 * @property integer $status
 * @property integer $auth_item_id
 * @property string $created_by
 * @property string $create_date
 * @property string $updated_by
 * @property string $update_date
 *
 * The followings are the available model relations:
 * @property SystemMenu $parent
 * @property SystemMenu[] $systemMenus
 */
class SystemMenu extends CActiveRecord {

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return SystemMenu the static model class
     */
    public static function model($className = __CLASS__) {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName() {
        return '{{system_menu}}';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules() {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('name, status', 'required'),
            //array('name, display_order, status, created_by, create_date, updated_by, update_date', 'required'),
            //array('parent_id', 'numerical', 'integerOnly' => true),
            array('parent_id', 'safe'),
            array('auth_item_id', 'numerical', 'integerOnly' => true),
            //array('parent_id, display_order, status, auth_item_id', 'numerical', 'integerOnly' => true),
            array('name, link', 'length', 'max' => 255),
            array('description', 'length', 'max' => 1000),
            array('created_by, updated_by', 'length', 'max' => 50),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, parent_id, name, link, display_order, description, status, auth_item_id, created_by, create_date, updated_by, update_date', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations() {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
        return array(
            'id' => 'ID',
            'parent_id' => 'Parent',
            'name' => 'Name',
            'link' => 'Link',
            'level' => 'Level',
            'display_order' => 'Display Order',
            'description' => 'Description',
            'status' => 'Status',
            'auth_item_id' => 'Auth Item',
            'created_by' => 'Created By',
            'create_date' => 'Create Date',
            'updated_by' => 'Updated By',
            'update_date' => 'Update Date',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search() {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('id', $this->id);
        $criteria->compare('parent_id', $this->parent_id);
        $criteria->compare('name', $this->name, true);
        $criteria->compare('link', $this->link, true);
        $criteria->compare('level', $this->level);
        $criteria->compare('display_order', $this->display_order);
        $criteria->compare('description', $this->description, true);
        $criteria->compare('status', $this->status);
        $criteria->compare('auth_item_id', $this->auth_item_id);
        $criteria->compare('created_by', $this->created_by, true);
        $criteria->compare('create_date', $this->create_date, true);
        $criteria->compare('updated_by', $this->updated_by, true);
        $criteria->compare('update_date', $this->update_date, true);

        return new CActiveDataProvider($this, array(
                    'criteria' => $criteria,
                    'pagination' => array(
                        'pageSize' => LGHelpers::getPageSize($this->count()),
                    ),
                    'sort' => array(
                        'defaultOrder' => array(
                            //'name' => CSort::SORT_ASC,
                        )
                    ),
                ));
    }

    public function getAllChilds() {
        $user = user();

        $userId = $user->id;

        $authManager = new RDbAuthManager();

        $tasks = $authManager->getTasks($userId);

        $subitems = array();
        if ($this->childs)
            foreach ($this->childs as $child) {
                $subitems[] = $child->getAllChilds();
            }
        $returnarray = array('label' => $this->name, 'url' => array($this->link));
        if ($subitems != array())
            $returnarray = array_merge($returnarray, array('items' => $subitems));

        return $returnarray;
    }

    public function getListSystemMenu() {
        $paginate = new CPagination();
        $paginate->pageSize = LGHelpers::getPageSize($this->count());

        $myArr = $this->getDataForIndex();

        $dataProvider = new CArrayDataProvider($myArr);
        $dataProvider->pagination = $paginate;
        $sort = new CSort;
        $sort->attributes = array(
            'name',
            'display_order',
           
        );
        $sort->defaultOrder= array(
                            //'name' => CSort::SORT_ASC,
                            //'display_order' => CSort::SORT_ASC,
                        );
        $dataProvider->sort = $sort;
        return $dataProvider;
    }

    public function getStatus() {
        return CHtml::listData(LGHelpers::getStatusCategory(), 'id', 'name');
    }

    public function searchByDisplayOrder($order, $parent_id) {
        $criteria = new CDbCriteria();
        $criteria->addCondition("display_order = :display_order && parent_id = :parent_id");
        $criteria->params = array(':display_order' => $order, ':parent_id' => $parent_id);
        $result = $this->findAll($criteria);
        return $result[0];
    }

    public function searchByParentID($parent_id) {
        $criteria = new CDbCriteria();
        $criteria->addCondition("parent_id = :parent_id");
        $criteria->params = array(':parent_id' => $parent_id);
        $criteria->order = 'display_order ASC';
        return $this->findAll($criteria);
    }

    public function getMaxDisplayOrder($parent_id) {
        $criteria = new CDbCriteria();
        $criteria->select = 'max(display_order) as display_order';
        $criteria->addCondition("parent_id = :parent_id");
        $criteria->params = array(':parent_id' => $parent_id);
        return $this->find($criteria);
    }

    public function getMinDisplayOrder($parent_id) {
        $criteria = new CDbCriteria();
        $criteria->select = 'min(display_order) as display_order';
        $criteria->addCondition("parent_id = :parent_id");
        $criteria->params = array(':parent_id' => $parent_id);
        return $this->find($criteria);
    }

    public function getDataForIndex($arr = NULL) {

        if (!$arr)
            $arr = array();
        $finalArray = array();
        $arr = LGHelpers::buildTreeArray($this->getAllParentAndChildSystemMenu($this->status, $this->name));
        LGHelpers::exposeTreeArray($arr, $finalArray, '|— ');
        $count = 0;

        foreach ($finalArray as $data) {
            $max_order = $this->getMaxDisplayOrder($data['parent_id']);
            $min_order = $this->getMinDisplayOrder($data['parent_id']);
            if ((int) $max_order['display_order'] == (int) $min_order['display_order']) {
                $finalArray[$count]['order_column'] =
                        '<input class="icon up disable" type="button">'
                        . '<input class="icon down disable" type="button">';
            } else if ((int) $data['display_order'] == (int) $min_order['display_order']) {
                $finalArray[$count]['order_column'] =
                        '<input class="icon down" onclick="js:LGCMS.ajaxCallback(&quot;'.Yii::app()->baseUrl.'/systemmenu/order?id=' . $data['id'] . '&amp;order=' . $data['display_order'] . '&amp;action=down&quot;)" name="yt2" type="button">'
                        . '<input class="icon up disable" type="button">';
            } else if ((int) $data['display_order'] == (int) $max_order['display_order']) {
                $finalArray[$count]['order_column'] =
                        '<input class="icon down disable" type="button">'
                        . '<input class="icon up" onclick="js:LGCMS.ajaxCallback(&quot;'.Yii::app()->baseUrl.'/systemmenu/order?id=' . $data['id'] . '&amp;order=' . $data['display_order'] . '&amp;action=up&quot;)" name="yt2" type="button">';
            } else {
                $finalArray[$count]['order_column'] =
                        '<input class="icon down" onclick="js:LGCMS.ajaxCallback(&quot;'.Yii::app()->baseUrl.'/systemmenu/order?id=' . $data['id'] . '&amp;order=' . $data['display_order'] . '&amp;action=down&quot;)" name="yt2" type="button">'
                        . '<input class="icon up" onclick="js:LGCMS.ajaxCallback(&quot;'.Yii::app()->baseUrl.'/systemmenu/order?id=' . $data['id'] . '&amp;order=' . $data['display_order'] . '&amp;action=up&quot;)" name="yt2" type="button">';
            }

            $count++;
        }
        return $finalArray;
    }

    public function getAllParentAndChildSystemMenu($statusFilter = '', $nameSearch = '') {
        $arr = array();
        $categoryData = NULL;

        if ($statusFilter != '') {
            $criteria = new CDbCriteria();
            $criteria->addCondition("status = :status");
            $criteria->params = array(':status' => $statusFilter);
            $systemMenuData = $this->findAll($criteria, array('order' => 'display_order ASC'));
        } else if ($nameSearch != '') {
            $criteria = new CDbCriteria();
            $criteria->addSearchCondition('name', $nameSearch, true);
            $systemMenuData = $this->findAll($criteria, array('order' => 'display_order ASC'));
        } else if ($nameSearch != '' && $statusFilter != '') {
            $criteria = new CDbCriteria();
            $criteria->addCondition("name = :name and status =:status");
            $criteria->params = array(':name' => $nameSearch, ':status' => $statusFilter);
            $systemMenuData = $this->findAll($criteria, array('order' => 'display_order ASC'));
        } else {
            $systemMenuData = $this->findAll(array('order' => 'display_order ASC'));
        }
        foreach ($systemMenuData as $model) {
            $arr[$model->id] = array("id" => $model['id'],
                "parent_id" => $model['parent_id'],
                "order" => $model['display_order'],
                "name" => $model['name'],
                "link" => $model['link'],
                'description' => $model['description'],
                'status' => $model['status'],
                'display_order' => $model['display_order'],
                'updated_by' => $model['updated_by'],
                'update_date' => $model['update_date'],
                'icon_active' => $model['icon_active'],
                'order_column' => '',
            );
        }
        return $arr;
    }

    public $icon_active;
    public $old_parent_id;

    protected function afterFind() {
        $this->update_date = strtotime($this->update_date);
        $this->update_date = date(LGConstant::DATE_FORMAT, $this->update_date);
        // display icon in Active column
        if ($this->status == 1) {
            $this->icon_active = "icon active";
        } else {
            $this->icon_active = "icon inactive";
        }

        parent::afterFind();
    }

    public function beforeSave() {
        if (parent::beforeSave()) {
            $current_date = date(LGConstant::DATE_FORMAT_FOR_DATABASE);
            $logedInUser = User::model()->findByPk(Yii::app()->user->id);
            if ($this->create_date == NULL) {
                $this->create_date = $current_date;
            }

            if ($this->created_by == NULL) {
                $this->created_by = $logedInUser->username;
            }

            $max_category = $this->getMaxDisplayOrder($this->parent_id);
            $this->display_order = $max_category['display_order'] + 1;

            if ($this->parent_id == NULL) {
                $this->parent_id = 0;
            }

            $this->update_date = $current_date;
            $this->updated_by = $logedInUser->username;

            return true;
        }
        else
            return false;
    }

    function afterSave() {
        if (!$this->isNewRecord) {
            $system_menu = $this->searchByParentID($this->parent_id);
            $count = 1;
            foreach ($system_menu as $data) {
                $child_system_menu = $this->findByPk($data['id']);
                $child_system_menu->display_order = $count;
                $child_system_menu->saveAttributes(array('display_order'));
                $count++;
            }
            $system_menu_parent = $this->find('parent_id = :parent_id', array(':parent_id' => $this->parent_id));
            $parent = $this->findByPk($system_menu_parent->parent_id);
            if ($parent != NULL) {
                $list_system_menu_parent = $this->searchByParentID($parent->parent_id);
                $count_parent = 1;
                foreach ($list_system_menu_parent as $value) {
                    $child_system_menu_parent = $this->findByPk($value['id']);
                    $child_system_menu_parent->display_order = $count_parent;
                    $child_system_menu_parent->saveAttributes(array('display_order'));
                    $count_parent++;
                }
            }
            if ($this->parent_id != $this->old_parent_id) {
                if (!$this->isNewRecord) {
                    $old_system_menu = $this->searchByParentID($this->old_parent_id);
                    $count_old_parent = 1;
                    foreach ($old_system_menu as $data) {
                        $child_system_menu = $this->findByPk($data['id']);
                        $child_system_menu->display_order = $count_old_parent;
                        $child_system_menu->saveAttributes(array('display_order'));
                        $count_old_parent++;
                    }
                }
            }
        }
        parent::afterSave();
    }

    public function getListData($currentId) {
        $models = SystemMenu::model()->findAll(array('order' => 'display_order asc'));
        $srcArr = array();
        foreach ($models as $model) {
            $srcArr[$model->id] = array("id" => $model->id, "parent_id" => $model->parent_id, "order" => $model->display_order, "name" => $model->name);
        }

        $treeArray = LGHelpers::buildTreeArray($srcArr);

        $outArray = array();
        if ($currentId != null && $currentId != 0) {
            LGHelpers::exposeTreeArray($treeArray, $outArray, '- ', array($currentId));
        }
        else
            LGHelpers::exposeTreeArray($treeArray, $outArray);

        foreach ($outArray as $data)
            $finalArray[] = array("id" => $data['id'], "name" => $data['indent'] . $data['name']);

        return CHtml::listData($finalArray, 'id', 'name');
    }

    public function getSystemMenuForUpdate($parent_id, $display_order) {
        $criteria = new CDbCriteria();
        $criteria->addCondition("parent_id = :parent_id and display_order >= :display_order");
        $criteria->params = array(':parent_id' => $parent_id, ':display_order' => $display_order);
        //$criteria->order = 'display_order ASC';
        return $this->findAll($criteria);
    }

    public function getAllSystemMenuNodesHaveRootSpecifiedID($id, $arr = NULL) {
        if (!$arr)
            $arr = array();

        $system_menu = $this->searchByParentID($id);
        foreach ($system_menu as $data) {
            $arr[] = array('id' => $data['id'], 'name' => $data['name']);
            $arr = $this->getAllSystemMenuNodesHaveRootSpecifiedID($data['id'], $arr);
        }
        return $arr;
    }

    public function beforeDelete() {
        if (parent::beforeDelete()) {
            $list_child_system_menu = $this->getAllSystemMenuNodesHaveRootSpecifiedID($this->id);
            foreach ($list_child_system_menu as $data) {
                $system_menu = new SystemMenu();
                $system_menu->deleteByPk($data['id']);
            }
            return true;
        } else {
            return false;
        }
    }

    public function afterDelete() {
        $list_system_menu = $this->getSystemMenuForUpdate($this->parent_id, $this->display_order);
        foreach ($list_system_menu as $value) {
            $system_menu = new SystemMenu();
            $system_menu_entity = $system_menu->model()->findByPk($value['id']);
            $system_menu_entity->display_order = (int) $value['display_order'] - 1;
            $system_menu_entity->update();
        }
        parent::afterDelete();
    }

    public function getMenusByUser($userId) {
        // get tasks from user
        $sql = 'SELECT t1.id 
                FROM ' . AuthItem::model()->tableName() . ' t1
                WHERE t1.type=:type AND t1.name in (SELECT child 
                    FROM ' . AuthAssignment::model()->tableName() . ' 
                    LEFT JOIN ' . Yii::app()->authManager->itemChildTable . ' ON parent=itemname WHERE userid=:userid)';

        $command = Yii::app()->db->createCommand($sql);
        $command->bindValue(':type', AuthorizationType::TASK);
        $command->bindValue(':userid', $userId);

        $tasks = array();
        foreach ($command->queryAll() as $row)
            $tasks[] = $row['id'];

        // get all menus 
        $models = $this->model()->findAll('status=1');
        $modelArr = array();
        foreach ($models as $model) {
            $url = (is_null($model->link) || $model->link == '' || $model->link == 'javascript:void(0);') ? 'javascript:void(0);' : array($model->link);
            $modelArr[$model->id] = array('id' => $model->id, 'parent_id' => $model->parent_id, 'order' => $model->display_order, 'label' => $model->name, 'url' => $url, 'auth_item_id' => $model->auth_item_id);
        }

        // check access permission 
        $lgUser = new LGUser();
        $menuArray = array();
        foreach ($modelArr as $a) {
            if (is_null($a['auth_item_id'])) {
                $menuArray[$a['id']] = $a;
            } else {
                if (in_array($a['auth_item_id'], $tasks)) {

                    $isExist = array_key_exists($a['parent_id'], $modelArr);
                    if ($isExist) {
                        $parent = $modelArr[$a['parent_id']];
                        if (is_null($parent['auth_item_id']) || in_array($parent['auth_item_id'], $tasks))
                            $menuArray[$a['id']] = $a;
                    }
                    else
                        $menuArray[$a['id']] = $a;
                }
            }
        }

        return $lgUser->checkSuperAdmin() === true ? LGHelpers::buildTreeArray($modelArr) : LGHelpers::buildTreeArray($menuArray);
    }

    public function setChildIsActive($id, $status) {
        $items = SystemMenu::model()->searchByParentID($id);
        foreach ($items as $data) {
            $item = SystemMenu::model()->findByPk($data['id']);
            $item->status = $status;
            $item->saveAttributes(array('status'));
            SystemMenu::model()->setChildIsActive($data['id'], $status);
        }
    }

}